package org.ytor.common.util.jvm;

import java.lang.management.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * created by yangtong on 2025/5/21 22:47:20
 */
public class Jvms {

    /**
     * 获取堆的使用情况
     */
    public static HeapInfo getHeapInfo() {
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heap = memoryMXBean.getHeapMemoryUsage();

        long init = heap.getInit();         // 初始堆大小（由-Xms指定）
        long used = heap.getUsed();         // 实际使用
        long committed = heap.getCommitted(); // 已向操作系统申请的内存
        long max = heap.getMax();           // 最大堆大小（由-Xmx指定）

        // 计算剩余空间，注意 max 可能为 -1（未设定上限）
        long free = (max > 0) ? (max - used) : (committed - used);

        HeapInfo heapInfo = new HeapInfo();
        heapInfo.setInit(init);
        heapInfo.setUsed(used);
        heapInfo.setMax(max);
        heapInfo.setCommitted(committed);
        heapInfo.setFree(free);

        return heapInfo;
    }

    /**
     * 获取非堆内存（Metaspace）
     */
    public static MemoryInfo getNonHeapInfo() {
        MemoryUsage usage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
        return new MemoryInfo(usage);
    }

    /**
     * 获取所有内存池（Eden、Old、Survivor、Metaspace 等）
     */
    public static List<MemoryPoolInfo> getMemoryPools() {
        List<MemoryPoolInfo> list = new ArrayList<>();
        for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
            list.add(new MemoryPoolInfo(pool.getName(), pool.getType().toString(), pool.getUsage()));
        }
        return list;
    }

    /**
     * 获取 GC 信息
     */
    public static List<GcInfo> getGcInfo() {
        List<GcInfo> list = new ArrayList<>();
        for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
            list.add(new GcInfo(gc.getName(), gc.getCollectionCount(), gc.getCollectionTime()));
        }
        return list;
    }

    /**
     * 获取线程信息
     */
    public static ThreadInfo getThreadInfo() {
        ThreadMXBean tm = ManagementFactory.getThreadMXBean();
        return new ThreadInfo(
                tm.getThreadCount(),
                tm.getPeakThreadCount(),
                tm.getDaemonThreadCount(),
                tm.getTotalStartedThreadCount()
        );
    }

    /**
     * 获取类加载信息
     */
    public static ClassInfo getClassLoadingInfo() {
        ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean();
        return new ClassInfo(cl.getLoadedClassCount(), cl.getTotalLoadedClassCount(), cl.getUnloadedClassCount());
    }

    /**
     * 获取 JVM 属性（启动参数、系统属性等）
     */
    public static Map<String, Object> getJvmProperties() {
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("jvmName", runtime.getVmName());
        map.put("jvmVendor", runtime.getVmVendor());
        map.put("jvmVersion", runtime.getVmVersion());
        map.put("startTime", runtime.getStartTime());
        map.put("uptime", runtime.getUptime());
        map.put("inputArgs", runtime.getInputArguments());
        map.put("systemProperties", runtime.getSystemProperties());
        return map;
    }
}
